﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Drawing;

namespace AcesHigh.GUI
{
    internal delegate void PictureCardRemove(DeckPanel panel, PictureCard card);
    internal delegate void PictureCardCLicked(DeckPanel panel, PictureCard card);

    /*
     * Class that represents a basic panal that contains Picture Cards.
     */
    internal class DeckPanel : Panel
    {
        public event PictureCardRemove pictureCardRemoveEvent;
        public event PictureCardCLicked pictureCardClickEvent;

        private int picCardX = 0;
        private int picCardY = 0;
        protected const int X_OFFSET = 0;
        protected const int Y_OFFSET = 3;

        // Holds a reference to Picture Cards currently being displayed
        // on this panel
        protected List<PictureCard> picCards;

        internal DeckPanel()
        {
            InitPanel();
            InitPictureCardList();
            InitEventHandlers();
        }

        private void InitPictureCardList()
        {
            picCards = new List<PictureCard>();
        }

        // Event fired when an item is removed from the picCards list
        private void InitEventHandlers()
        {
            this.pictureCardRemoveEvent += new PictureCardRemove(DeckPanel_pictureCardRemoveEvent);
        }

        private void InitPanel()
        {
            this.BackColor = Color.ForestGreen;
            this.Size = new Size(72, 96);
            this.MinimumSize = this.Size;
            this.BackColor = Color.Transparent;
            this.AutoSize = true;
            this.AllowDrop = true;

            // Show and empty image as default
            this.Controls.Add(new EmptyDeckPictureBox());
        }

        // Add a picture card to this panel. PictureCard reference is added
        // to this panels controls and to the picList list.
        internal virtual void addPictureCard(PictureCard picCard)
        {
            picCard.Location = new System.Drawing.Point(picCardX + X_OFFSET, picCardY += Y_OFFSET);
            this.Controls.Add(picCard);

            // Makes this card on top and ensures last card added to picCards is the top card.
            picCard.BringToFront();
            picCards.Add(picCard);

            updateClickHandler();
        }

        /**
         * Methdod that ensures event handlers are assigned to the top card
         * being displayed in this panel
         */
        internal virtual void updateClickHandler()
        {
            int count = picCards.Count;

            if (count == 0) return;

            if (count > 1)
            {
                removePictureCardEvents();

            }
            addPictureCardEvents();
            
        }

        // Adds double click event handler to the top card of this panel
        // Should overriden to add more event handlers
        internal virtual void addPictureCardEvents()
        {
            picCards[picCards.Count - 1].DoubleClick += new EventHandler(CardDoubleClick);
        }

        // removes double click event handler from the top card of this panel
        // Should overriden to remove more event handlers
        internal virtual void removePictureCardEvents()
        {
            (picCards[picCards.Count - 2]).DoubleClick -= CardDoubleClick;
        }

        // Method called when the top card is cliked.
        internal virtual void CardDoubleClick(object obj, EventArgs args)
        {
            if (pictureCardClickEvent != null)
            {
                pictureCardClickEvent(this, (PictureCard)obj);
            }
        }

        // Returns the Picture Card that is currently on top.
        // PictureCard is actually returned from the list as the last element
        // which is guarantedd to be the top card displayed.
        public PictureCard TopPictureCard
        {
            get
            {
                if (picCards.Count > 0)
                {
                    return picCards[picCards.Count - 1];
                }
                else
                {
                    return null;
                }
            }
        }

        // Returns true if there are no Picture Cards currently being displayed/contained in picCards list.
        public bool IsEmpty
        {
            get { return (picCards.Count == 0); }
        }


        // Method called when a card is removed from the picCards list.
        protected void DeckPanel_pictureCardRemoveEvent(DeckPanel panel, PictureCard picCard)
        {
            if (panel == this)
            {
                // As the card is no longer in the list we can remove it from the panel display
                this.Controls.Remove(picCard);
            }
        }

        // Removes the last card (top card) in the picCards list and returns it
        internal PictureCard PopPictureCard()
        {
            PictureCard card = picCards[picCards.Count - 1];
            removeCard(card);
            return card;
        }

        // Remove a card from the list and fire pictureCardRemoveEvent
        private void removeCard(PictureCard picCard)
        {
            picCards.Remove(picCard);
            pictureCardRemoveEvent(this, picCard);
        }
    }

}
